#pragma once
#include<iostream>
#include<cstring>
#include<assert.h>
using namespace std;

class String
{
    size_t _size;
    size_t _capacity;
    char* _str;
    static const size_t npos = -1; 
    // 特例：const类型的静态成员变量，且变量类型为整数，就可以给缺省值

    // static const double d = 3.1; // err
public:

    // 构造、析构
    String();
    String(const char* s);
    String(size_t n, char c);
    ~String();

    String(const String& str);
    String& operator= (const String& str);
    // String& operator= (String str);

    // 访问相关
    const char* c_str() const
    { return _str; }

    char& operator[](size_t pos) { return _str[pos]; }

    const char& operator[](size_t pos) const
    { return _str[pos]; }

    // 空间相关
    size_t size() const { return _size; }
    size_t capacity() const { return _capacity; }
    void reserve(size_t n);
    void resize(size_t n);
    
    // 迭代器
    typedef char* iterator;
    typedef const char* const_iterator; // 指向的内容不可修改

    iterator begin() { return _str; };
    iterator end() { return _str + _size; }

    const_iterator begin() const
    { return _str; };
    const_iterator end() const
    { return _str + _size; }

    // 插入、删除
    void push_back(char c);
    String& operator+=(char c);
    String& operator+=(const char* s);
    String& operator+=(const String& str);

    String& insert(size_t pos, const char* s);
    String& erase(size_t pos, size_t len = npos);
    void clear() { _size = 0, _str[0] = '\0'; }

    // 查找
    size_t find(char c, size_t pos = 0) const;
    size_t find(const char* s, size_t pos = 0) const;
    size_t find(const String& str, size_t pos = 0) const;

    // 
    void swap(String& str);

    String substr(size_t pos = 0, size_t len = npos) const;

    // 比较大小
    bool operator< (const String& str) const;
    bool operator> (const String& str) const;
    bool operator== (const String& str) const;
    bool operator!= (const String& str) const;
    bool operator<= (const String& str) const;
    bool operator>= (const String& str) const;

    // friend ostream& operator<< (ostream& out, const String& str);
    // friend istream& operator>> (istream& in, String& str);
};

// String::npos = -1; // 放.h会包含2份

istream& operator>> (istream& in, String& str);
ostream& operator<< (ostream& out, const String& str);
